package com.mcptt.db.model;

import java.io.File;
import java.io.Serializable;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.os.Parcel;
import android.os.Parcelable;

import com.cloudptt.api.comm.Common;
import com.cloudptt.api.comm.FileOperation;
import com.cloudptt.api.pjsip.api.MessageInfo;
import com.cloudptt.api.product.log.Log;
import com.cloudptt.api.product.res.Resource;
import com.mcptt.config.body.info.mcdata.FileMataInfo;
import com.mcptt.db.DbConst;

public class SessionInfo implements Parcelable//, Parcelable
{
	public static final String HTTP_KEY = "http://";;
	public static final String Sub_Url = "/as/msf/";;

	public static final String MsgType_Desc_Oto_SDS = "one-to-one-sds";//一对一短数据
	public static final String MsgType_Desc_Group_SDS = "group-sds";//群组短数据
	public static final String MsgType_Desc_Oto_FD = "one-to-one-fd";//一对一文件发布
	public static final String MsgType_Desc_Group_FD = "group-fd";//群组文件发布
	public static final String MsgType_Desc_Msf_REQ = "msf-desc-req";//用户请求媒体存储资源的HTTP绝对地址
	public static final String MsgType_Desc_Msc_RES = "msc-dsc-res";//表示对媒体资源HTTP地址请求的响应
	public static final String MsgType_Desc_Notify = "notify";//Controlling Server向MCData客户端发送文件失效通知
	public static final String MsgType_Desc_Oto_SDS_Session = "one-to-one-sds-session";//客户端希望开始一对一SDS会话
	public static final String MsgType_Desc_Group_SDS_Session = "group-sds-session";//客户端希望开始群组SDS会话

	public static final String MsgType_Desc_Msf_Disc_Req = "msf-disc-req";//客户端希望开始群组SDS会话
	public static final String MsgType_Desc_Msf_Disc_Res = "msf-disc-res";//客户端希望开始群组SDS会话

	public static final String MsgType_Desc_Call_History = "call-history";//客户端希望开始群组SDS会话

	public static final int ContentType_Text = 0x1;//TEXT：1
	public static final int ContentType_Binary = 0x2;//BINARY： 2
	public static final int ContentType_Hyperlink = 0x3;//HYPERLINKS：3
	public static final int ContentType_FileURL = 0x4;//FILEURL：4（URL标准可参照RFC 1738）
	public static final int ContentType_Location = 0x5;//  LOCATION：5

	public static final byte Status_SDS_BASE =0;
	public static final byte Status_SDS_UNDELIVERED =1;
	public static final byte Status_SDS_DELIVERED =2;
	public static final byte Status_SDS_READ =3;
	public static final byte Status_SDS_DELIVERED_READ =4;

	public static final byte Status_FD_REQUEST_ACCEPTED =1;
	public static final byte Status_FD_REQUEST_REJECTED=2;
	public static final byte Status_FD_COMPLETED=3;
	public static final byte Status_FD_DEFERRED=4;

	public final static int Filetype_File = 1;
	public final static int Filetype_Pic = 2;
	public final static int Filetype_Voice = 3;
	public final static int Filetype_Video = 4;

	public final static int Direction_Type_Send = 1;
	public final static int Direction_Type_Receive = 2;

	public final static int Type_Normal = 1;
	public final static int Type_Func = 2;

	public static byte DELIVERY = 0x1;
	public static byte READ = 0x2;
	public static byte DOWNLAOD = 0x1;

//	private int type = Type_Normal;
	private String conversationId = null;
	private String msgId = null;

	private AddrInfo peerAddrInfo = null;  //接受方属性
	private AddrInfo senderAddrInfo = null;  //发送方属性
		 	//消息类型(图片、文字)
	private String msgType = MsgType_Desc_Oto_SDS;
	private int contentType = ContentType_Text;
	private int direction = Direction_Type_Send;    			//收发标记（1：发  2：收）
	private String content=""; //文字or fileUrl
	private String localPath="";
	private String fileMetaData = "";
	private long date=0;				//发送时间
	private String dateStr="0";
	private int status = Status_SDS_BASE;  			//消息状态（1：已读 2：发送失败 3：未读 4：未接听 5：已接听 6：主呼）
	private String controllerPsi = "";//只有收消息有值 供回执使用
	private int dispositionReqType = DELIVERY+READ;

	public SessionInfo(AddrInfo peerAddrInfo,AddrInfo sender,MessageInfo info)
	{

		this.conversationId =info.getConversationId();
		this.msgId = info.getMsgId();

		this.peerAddrInfo = peerAddrInfo;
		this.senderAddrInfo = sender;

		this.msgType = info.getMsgType();
		this.contentType = info.getContentType();
		this.direction = Direction_Type_Receive;
		this.content = info.getContent();
		this.localPath = "";
		this.fileMetaData = info.getFileMetaData();

		this.date = Common.currentTimeMillis();
		this.dateStr = Common.getDateAndTime(date);
		this.status = Status_SDS_BASE;
		if(isFdMsg())
		{
			this.status = Status_FD_REQUEST_ACCEPTED;
		}
		this.controllerPsi = info.getControllerPsi();
		this.dispositionReqType = info.getDispositionReqType();
	}

	public SessionInfo(AddrInfo peerAddrInfo,AddrInfo sender,int contentType,int direction,String content,int dispositionReqType)
	{
		this.conversationId =Common.to16LenStr(peerAddrInfo.getAddrId());
		this.msgId = Common.getDateMillSeconds();

		this.peerAddrInfo = peerAddrInfo;
		this.senderAddrInfo = sender;

		boolean isGroupType = peerAddrInfo.isGroupType();
		this.msgType = getMsgTypeByAddrTypeAndContentType(isGroupType,contentType);
		this.contentType = contentType;
		this.direction = direction;
		this.content = content;
		this.localPath = "";
		this.fileMetaData = "";

		this.date = Common.currentTimeMillis();
//		long val = Common.currentTimeMillis();
		this.dateStr = Common.getDateAndTimeStr();
		Log.debug(this.getClass(),"SessionInfo dateStr = " + dateStr);
		this.status = Status_SDS_BASE;
		if(isFdMsg())
		{
			this.status = Status_FD_REQUEST_ACCEPTED;
		}
		this.dispositionReqType = dispositionReqType;
	}

	public SessionInfo(AddrInfo peerAddrInfo, AddrInfo sender, int contentType, int direction, String fileUrl, String localFile, String fileMetaData, int dispositionReqType)
	{
		this.conversationId =Common.to16LenStr(peerAddrInfo.getAddrId());
		this.msgId = Common.getDateMillSeconds();

		this.peerAddrInfo = peerAddrInfo;
		this.senderAddrInfo = sender;

		boolean isGroupType = peerAddrInfo.isGroupType();
		this.msgType = getMsgTypeByAddrTypeAndContentType(isGroupType,contentType);
		this.contentType = contentType;
		this.direction = direction;
		this.content = fileUrl;
		this.localPath = localFile;
		this.fileMetaData = fileMetaData;

		this.date = Common.currentTimeMillis();
//		long val = Common.currentTimeMillis();
		this.dateStr = Common.getDateAndTimeStr();
		Log.debug(this.getClass(),"SessionInfo dateStr = " + dateStr);
		this.status = Status_SDS_BASE;
		if(isFdMsg())
		{
			this.status = Status_FD_REQUEST_ACCEPTED;
		}
		this.dispositionReqType = dispositionReqType;
	}


	public SessionInfo(Cursor c) 
	{
		ContentValues args = new ContentValues();
		DatabaseUtils.cursorRowToContentValues(c, args);
		createFromContentValue(args);
	}

	private SessionInfo(Parcel in) {
        conversationId = getReadParcelableString(in.readString());
        msgId = getReadParcelableString(in.readString());

		int peerType = in.readInt();
		String peerAddrId = getReadParcelableString(in.readString());
		String peerName = getReadParcelableString(in.readString());
		this.peerAddrInfo = new AddrInfo(peerType,peerName,peerAddrId,0);

		int senderType = in.readInt();
		String senderAddrId = getReadParcelableString(in.readString());
		String senderName = getReadParcelableString(in.readString());
		this.senderAddrInfo = new AddrInfo(senderType,senderName,senderAddrId,0);

		this.msgType = getReadParcelableString(in.readString());
		this.contentType = in.readInt();
		this.direction = in.readInt();
		this.content = getReadParcelableString(in.readString());
		this.localPath = getReadParcelableString(in.readString());
		this.fileMetaData = getReadParcelableString(in.readString());
		this.date = in.readLong();//getReadParcelableString(in.readString());
		this.dateStr = getReadParcelableString(in.readString());
		this.status = in.readInt();
		this.controllerPsi = getReadParcelableString(in.readString());
		this.dispositionReqType = in.readInt();
    }
   /**
     * Parcelable creator. So that it can be passed as an argument of the aidl
     * interface
     */
    public static final Creator<SessionInfo> CREATOR = new Creator<SessionInfo>() {
        public SessionInfo createFromParcel(Parcel in) {
            return new SessionInfo(in);
        }

        public SessionInfo[] newArray(int size) {
            return new SessionInfo[size];
        }
    };

    /**
     * @see Parcelable#describeContents()
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * @see Parcelable#writeToParcel(Parcel, int)
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(getWriteParcelableString(conversationId));
        dest.writeString(getWriteParcelableString(msgId));

		dest.writeInt(peerAddrInfo.getType());
		dest.writeString(getWriteParcelableString(peerAddrInfo.getAddrId()));
		dest.writeString(getWriteParcelableString(peerAddrInfo.getName()));

		dest.writeInt(senderAddrInfo.getType());
		dest.writeString(getWriteParcelableString(senderAddrInfo.getAddrId()));
		dest.writeString(getWriteParcelableString(senderAddrInfo.getName()));

        dest.writeString(getWriteParcelableString(msgType));
		dest.writeInt(contentType);
		dest.writeInt(direction);
        dest.writeString(getWriteParcelableString(content));
		dest.writeString(getWriteParcelableString(localPath));
		dest.writeString(getWriteParcelableString(fileMetaData));
		dest.writeLong(date);//.writeString(getWriteParcelableString(date));
		dest.writeString(getWriteParcelableString(dateStr));

		dest.writeInt(status);
		dest.writeString(getWriteParcelableString(controllerPsi));
		dest.writeInt(dispositionReqType);
    }

    // Yes yes that's not clean but well as for now not problem with that.
    // and we send null.
    private String getWriteParcelableString(String str) {
        return (str == null) ? "null" : str;
    }

    private String getReadParcelableString(String str) {
        return str.equalsIgnoreCase("null") ? null : str;
    }
//
//
	public final void createFromContentValue(ContentValues args)
	{
		this.conversationId = args.getAsString(DbConst.COL_ConversationId);
		this.msgId = args.getAsString(DbConst.COL_MsgId);

		this.peerAddrInfo = new AddrInfo();

		int type = args.getAsInteger(DbConst.COL_PeerType);
		peerAddrInfo.setType(type);
		String tmp_s;
		tmp_s = args.getAsString(DbConst.COL_PeerAddrId);
		if(tmp_s != null) {
			peerAddrInfo.setAddrId(tmp_s);
		}
		tmp_s = args.getAsString(DbConst.COL_PeerName);
		if(tmp_s != null) {
			peerAddrInfo.setName(tmp_s);
		}


		this.senderAddrInfo = new AddrInfo();
		type = args.getAsInteger(DbConst.COL_PeerType);
		senderAddrInfo.setType(type);
		tmp_s = args.getAsString(DbConst.COL_LastSenderId);
		if(tmp_s != null) {
			senderAddrInfo.setAddrId(tmp_s);
		}
		tmp_s = args.getAsString(DbConst.COL_LastSenderName);
		if(tmp_s != null) {
			senderAddrInfo.setName(tmp_s);
		}

		this.msgType = args.getAsString(DbConst.COL_MsgType);
		this.direction = args.getAsInteger(DbConst.COL_Direction);
		this.contentType = args.getAsInteger(DbConst.COL_ContentType);
		this.localPath = args.getAsString(DbConst.COL_LocalPath);
		this.content = args.getAsString(DbConst.COL_Content);
		this.fileMetaData = args.getAsString(DbConst.COL_MetaData);

		this.date = args.getAsLong(DbConst.COL_Date);
		this.dateStr = Common.getDateAndTime(date);
		this.dispositionReqType = args.getAsInteger(DbConst.COL_DispositionReqType);
		this.status = args.getAsInteger(DbConst.COL_Status);
		this.controllerPsi = args.getAsString(DbConst.COL_PsiControl);
	}

	/**
	 * Pack the object content value to store
	 * 
	 * @return The content value representing the message
	 */
	public ContentValues getContentValues() {
		ContentValues cv = new ContentValues();

		cv.put(DbConst.COL_ConversationId, conversationId);
		cv.put(DbConst.COL_MsgId, msgId);

		cv.put(DbConst.COL_PeerType, peerAddrInfo.getType());
		cv.put(DbConst.COL_PeerAddrId, peerAddrInfo.getAddrId());
		cv.put(DbConst.COL_PeerName, peerAddrInfo.getName());

		cv.put(DbConst.COL_LastSenderType, peerAddrInfo.getType());
		cv.put(DbConst.COL_LastSenderId, senderAddrInfo.getAddrId());
		cv.put(DbConst.COL_LastSenderName, senderAddrInfo.getName());

		cv.put(DbConst.COL_MsgType, msgType);
		cv.put(DbConst.COL_Direction, direction);
		cv.put(DbConst.COL_ContentType, contentType);
		cv.put(DbConst.COL_Content, content);
		cv.put(DbConst.COL_LocalPath, localPath);
		cv.put(DbConst.COL_MetaData, fileMetaData);

		cv.put(DbConst.COL_Date, date);
		cv.put(DbConst.COL_DispositionReqType, dispositionReqType);
		cv.put(DbConst.COL_Status, status);
		cv.put(DbConst.COL_PsiControl, controllerPsi);
		return cv;
	}

	public static ContentValues getUpdateStatusContentValues(int status) {
		ContentValues cv = new ContentValues();
		cv.put(DbConst.COL_Status, status);
		return cv;
	}

	public SessionInfo toForwardSessionInfo(AddrInfo peerAddrInfo,AddrInfo senderAddrInfo,int reqType)
	{
		SessionInfo info = null;
		if(isFdMsg())
		{
			info = new SessionInfo(peerAddrInfo,senderAddrInfo,contentType,SessionInfo.Direction_Type_Send,content,localPath,fileMetaData,reqType);
		}
		else
		{
			info = new SessionInfo(peerAddrInfo,senderAddrInfo,contentType,SessionInfo.Direction_Type_Send,content,reqType);
		}
		return info;
	}

	public HistoryInfo toHistoryInfo()
	{
		HistoryInfo info = new HistoryInfo(peerAddrInfo);
		info.setLastSender(senderAddrInfo);
		info.setLastMsgContent(content);
		if(isFdMsg())
		{
			info.setLastMsgContent(fileMetaData);
		}

		info.setLastMsgDate(date);
		info.setLastContentType(contentType);

		return info;
	}

	public String getConversationId() {
		return conversationId;
	}

	public String getMsgId() {
		return msgId;
	}
	public AddrInfo getSenderAddrInfo() {
		return senderAddrInfo;
	}

//	public void setPeerAddrInfo(UserInfo peerAddrInfo) {
//		this.peerAddrInfo = peerAddrInfo;
//	}
	public AddrInfo getPeerAddrInfo() {
		return peerAddrInfo;
	}

	public String getMsgType() {
		return msgType;
	}

	public int getContentType() {
		return contentType;
	}

	public String getContent() {
		return content;
	}

	public String getContentDesc() {
		if(contentType == SessionInfo.ContentType_FileURL)
		{
			FileMataInfo fileMataInfo = FileMataInfo.parse(content);
			String type = fileMataInfo.getType();
			Log.debug(getClass(), "getView type = " + type);

			if(FileOperation.isPicture(type))
			{
				return Resource.getString("pic_flag");
			}
			else if(FileOperation.isAudio(type))
			{
				return Resource.getString("voice_flag");
			}
			else
			{
				return Resource.getString("file_flag");
			}
		}
		return content;
	}
	public String getLocalPath() {
		return localPath;
	}

	public MessageInfo toMessageInfo()
	{
		String funcUrl = senderAddrInfo.getAddrId();
		MessageInfo msgInfo = new MessageInfo(conversationId,msgId,msgType,contentType,content, fileMetaData,date/1000,dispositionReqType,controllerPsi,funcUrl);
		return msgInfo;
	}

	public void setContent(String content) {
		this.content = content;
	}
	public void updateLocalPath(String localPath) {
		Log.debug(this.getClass(), "updateLocalPath localPath = " + localPath);
		this.localPath = localPath;
	}
	public String getFileMetaData() {
		return fileMetaData;
	}

	public long getDate() {
		return date;
	}

	public String getDateStr() {
		return dateStr;
	}

	public void setDate(long date) {
		this.date = date;
	}
	public int getDirection() {
		return direction;
	}
	public void setDirection(int direction) {
		this.direction = direction;
	}
	public int getStatus() {
		return status;
	}

	public void setStatus(int status) {
		this.status = status;
	}

	public String getDscp()
	{
		return senderAddrInfo.getDscp();
	}

	public int getDispositionReqType() {
		return dispositionReqType;
	}

	public String getControllerPsi() {
		return controllerPsi;
	}

	private String getMsgTypeByAddrTypeAndContentType(boolean isGroupInfo,int contentType)
	{
		if(isGroupInfo)
		{
			if(ContentType_Text == contentType)
			{
				return MsgType_Desc_Group_SDS;
			}
			else
			{
				return MsgType_Desc_Group_FD;
			}
		}
		else
		{
			if(ContentType_Text == contentType)
			{
				return MsgType_Desc_Oto_SDS;
			}
			else
			{
				return MsgType_Desc_Oto_FD;
			}
		}
	}

	public boolean isShowStatus()
	{
		Log.debug(this.getClass(),"isShowStatus dispositionReqType = " + dispositionReqType);
		if(dispositionReqType > 0)
		{
			return true;
		}
		return false;
	}

	public boolean isFdMsg()
	{
		if(MsgType_Desc_Oto_FD.equals(msgType)
				|| MsgType_Desc_Group_FD.equals(msgType)
				|| MsgType_Desc_Msf_Disc_Req.equals(msgType))
		{
			return true;
		}
		return false;
	}

	public static boolean isFdMsg(String msgType)
	{
		if(MsgType_Desc_Oto_FD.equals(msgType)
				|| MsgType_Desc_Group_FD.equals(msgType)
				|| MsgType_Desc_Msf_Disc_Req.equals(msgType))
		{
			return true;
		}
		return false;
	}

	public boolean isOtoMsg()
	{
		if(MsgType_Desc_Oto_FD.equals(msgType)
				|| MsgType_Desc_Oto_SDS.equals(msgType)
				|| MsgType_Desc_Oto_SDS_Session.equals(msgType))
		{
			return true;
		}
		return false;
	}

	public boolean isGroupMsg()
	{
		if(MsgType_Desc_Group_FD.equals(msgType)
				|| MsgType_Desc_Group_SDS.equals(msgType)
				|| MsgType_Desc_Group_SDS_Session.equals(msgType))
		{
			return true;
		}
		return false;
	}

	public static boolean isOtoMsg(String msgType)
	{
		if(MsgType_Desc_Oto_FD.equals(msgType)
				|| MsgType_Desc_Oto_SDS.equals(msgType)
				|| MsgType_Desc_Oto_SDS_Session.equals(msgType))
		{
			return true;
		}
		return false;
	}

	public static boolean isGroupMsg(String msgType)
	{
		if(MsgType_Desc_Group_FD.equals(msgType)
				|| MsgType_Desc_Group_SDS.equals(msgType)
				|| MsgType_Desc_Group_SDS_Session.equals(msgType))
		{
			return true;
		}
		return false;
	}

//	public static String toMetaData(File file)
//	{
//		String fileName = file.getName();
//		String fileExtension = Common.getFileExtension(fileName);
//		String fileType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
//		long size = file.length();
//		StringBuffer strBuf = new StringBuffer("file-selector:");
//		strBuf.append("name:").append(fileName).append(" ");
//		strBuf.append("type:").append(fileType).append(" ");
//		strBuf.append("size:").append(size);
//		return  strBuf.toString();
//	}

	public String toString()
	{
		StringBuffer buffer = new StringBuffer("SessionInfo:");
		buffer.append("conversationId = ").append(conversationId).append(",");
		buffer.append("msgId = ").append(msgId).append(",");

		buffer.append("fromAddrInfo = ").append(peerAddrInfo).append(",");
		buffer.append("senderAddrInfo = ").append(senderAddrInfo).append(",");

		buffer.append("msgType = ").append(msgType).append(",");
		buffer.append("direction = ").append(direction).append(",");
		buffer.append("contentType = ").append(contentType).append(",");
		buffer.append("content = ").append(content).append(",");
		buffer.append("localPath = ").append(localPath).append(",");
		buffer.append("fileMetaData = ").append(fileMetaData).append(",");

		buffer.append("date = ").append(date).append(",");
		buffer.append("dateStr = ").append(dateStr).append(",");
		buffer.append("dispositionReqType = ").append(dispositionReqType).append(",");
		buffer.append("status = ").append(status).append(",");
		buffer.append("controllerPsi = ").append(controllerPsi).append(";");

		return buffer.toString();
	}
}
